package com.netnovelstore.annotation.impl;

import com.netnovelstore.annotation.UserNumberByToken;
import com.netnovelstore.config.JwtUtil;
import com.netnovelstore.pojo.Exception.IdentityException;
import com.netnovelstore.pojo.Exception.NotDataException;
import com.netnovelstore.pojo.Result;
import com.netnovelstore.pojo.User;
import com.netnovelstore.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

@Aspect
@Component
@Slf4j
public class JudgeOfIdentityImpl {
    private RedisUtil redisUtil;

    @Autowired
    public JudgeOfIdentityImpl(RedisUtil redisUtil) {
        this.redisUtil = redisUtil;
    }

    @Pointcut("@annotation(com.netnovelstore.annotation.JudgeOfIdentity)")
    public void methodInterPoint() {
    }

    @Around("methodInterPoint()")
    public Result methodProcessing(ProceedingJoinPoint joinPoint) throws Throwable {
        return this.processing(joinPoint);
    }

    private Result processing(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature method = (MethodSignature) joinPoint.getSignature();
        log.info(String.format("[%s] >>>>>>>>>", method.getName()));
        //获取参数列表
        Object[] args = joinPoint.getArgs();
        HttpServletRequest request = (HttpServletRequest) args[0];

        String token = request.getHeader("authorization");
        log.info(String.format("[%s] >>>>> token >>>> %s", method.getName(), token));
        //管理员用
        if (token.equals(JwtUtil.secret))
            return Result.defeat("需要指定账号");

        User user = (User) this.redisUtil.get(token);
        if (user == null) {
            throw new IdentityException("您未登录");
        }

        if (user.getUserNumber() == null) {
            throw new NotDataException("状态异常");
        }

        log.info(String.format("[%s] <<<< [ '%s' , %s ]", method.getName(), user.getUserName(), user.getUserNumber()));

        return (Result) joinPoint.proceed(ProcessUserNumber(joinPoint,user.getUserNumber()));

    }

    private Object[] ProcessUserNumber(ProceedingJoinPoint joinPoint,Integer userNumber) throws NoSuchMethodException {
        Object[] args = joinPoint.getArgs();
        // 方法签名
        Signature signature = joinPoint.getSignature();
        // 获取的是代理类的method对象
        Method method = ((MethodSignature) signature).getMethod();
        // 这个方法才是目标对象上有注解的方法
        Method realMethod = joinPoint.getTarget().getClass().getDeclaredMethod(signature.getName(), method.getParameterTypes());

        Annotation[][] parameterAnnotations = realMethod.getParameterAnnotations();
        log.info("run ProcessUserNumber");
        for (int i = 0; i < parameterAnnotations.length; i++) {
            for (Annotation annotation :
                    parameterAnnotations[i]) {

                System.out.println(annotation.annotationType());
                if (UserNumberByToken.class.equals(annotation.annotationType())) {
                    args[i] =  userNumber;
                    return args;
                }

            }
        }
        return args;
    }
}
